from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastapi.openapi.docs import get_swagger_ui_html as getSwaggerUIHtml
from fastapi.openapi.docs import get_swagger_ui_html as getSwaggerUIHtml
from src.backend.services.viteService import stopVite
from src.backend.middleware.corsMiddleware import setupCors
from src.backend.utils.envLoader import appConfig
from src.backend.middleware.viteProxyMiddleware import viteProxyMiddleware
from src.backend.middleware.filterMiddleware import FilterMiddleware
import os
from src.backend.routes import router as apiRouter
from src.backend.utils.prismaUtils import getPrismaClient
from contextlib import asynccontextmanager
import aiofiles
import aiofiles.os

@asynccontextmanager
async def lifespan(app: FastAPI):
    # 应用启动时执行
    await getPrismaClient()
    yield
    # 应用关闭时执行
    if appConfig.VITE_HMR:
        await stopVite()

app = FastAPI(
    title="CypressXPanel API",
    description="CypressXPanel 后端API文档",
    version="1.0.0",
    docs_url=None,  # 禁用默认的docs
    openapi_url="/api/openapi.json" if appConfig.FASTAPI_DOC else None,
    redoc_url=None,
    lifespan=lifespan
)

# 添加过滤中间件
app.add_middleware(FilterMiddleware)
setupCors(app)

# 挂载自动路由模块
app.include_router(apiRouter)

# 自定义Swagger UI路由
@app.get("/api/docs", include_in_schema=False)
async def SwaggerUI():
    return getSwaggerUIHtml(
        openapi_url="/api/openapi.json",
        title="CypressXPanel API",
        swagger_js_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js",
        swagger_css_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css",
    )

# 开发模式下注册 Vite 代理中间件
if appConfig.VITE_HMR:
    app.add_middleware(viteProxyMiddleware)

# 生产环境下的根路由
@app.get("/", response_class=HTMLResponse, include_in_schema=False)
async def readRoot():
    if appConfig.VITE_HMR:
        return HTMLResponse(content="<h1>Dev Mode</h1>")
    else:
        indexPath = os.path.join("dist", "frontend", "index.html")
        if await aiofiles.os.path.exists(indexPath):
            async with aiofiles.open(indexPath, mode='r', encoding="utf-8") as f:
                content = await f.read()
                return HTMLResponse(content=content)
        else:
            return HTMLResponse(content="404 Not Found", status_code=404)
